<?php
/**
 * Miffos framework
 * ----------------------------------------------
 *
 * Copyright (c) 2008, 2009 Martin Sadový (http://sodae.cz)
 *
 * This source file is subject to the "Miffos license" that is bundled
 * with this package in the file license.txt.
 *
 * @copyright  Copyright (c) 2008, 2009 Martin Sadový
 * @license    license.txt
 * @link       http://miffos.sodae.cz
 * @package    miffos
 * @version    $Id$
 */

  class Html /*implements ArrayAccess, IteratorAggregate*/
  {
    
    public $nameElement;
    
    public $attrs;
    
    private $emptyElement = array('img','hr','br','input','meta','area',
		                             	'base','col','link','param','basefont',
                                  'frame','isindex','wbr','embed');
    
    private $children = array();
  
    public $show = true;
  
    
    
    
    /**
     * Create Element
     * @param string $name
     * @param array $attrs
     * @return object
     */                        
    public static function el($name,$attrs=null)
    {
    
      $instance = new self;
      $instance->setElement($name);
      
      if(is_array($attrs)){
         $instance->attrs = $attrs;
         
      }elseif(is_string($attrs)){
         $instance->setHtml($attrs);

      }elseif($attrs instanceof Html){
         $instance->addChildren($attrs);
         
      }
      
      return $instance;
    }



    /**
     * Set name element
     * @param bool $show
     */
    public function setElement($name)
    {
      $this->nameElement = $name;
    }
    
    
    /**
     * Set show 
     * @param bool $show
     */     
    public function setShow($show)
    {
      $this->show = (bool)$show;
      return $this;
    }
    
    
    
    /**
     * Get show 
     * @return bool
     */     
    public function isShow()
    {
      return $this->show;
    }
    
    
    
    /**
     * Set attrs
     * @param string $name
     * @param mixed $value
     */     
    public function __set($name,$value)
    {
      $this->setAttrs($value,$name);
    }
    
    
    
    
    /**
     * Unset attrs
     * @param string $name
     */     
    public function __unset($name)
    {
      unset($this->attrs[$name]);
    }
    
    
    
    
    /**
     * Create Element
     * @param string $name
     * @param array $attrs
     * @return object
     */      
    public function __call($name,$args)
    {
      if(is_string($args[0])){
        $this->setAttrs($args[0],$name);
      }elseif(is_bool($args[0]) && ($args[0] == true)){
        $this->setAttrs($name);
      }
      
      return $this;
    }




    /**
     * Clean Content
     * @return string
     */
    public function cleanContent()
    {
      $this->children = array();
    }


    
    /**
     * Return start html element
     * @return string
     */          
    public function startElement()
    {
      if(empty($this->nameElement)) return '';
      $attrs = $this->getAttrs()?' '.$this->getAttrs():'';
      return '<'.$this->nameElement.$attrs.($this->isInEmpty()?'/>':'>');
    }
    
    
    
    
    /**
     * Return end html element
     * @return string
     */
    public function endElement()
    {
      if(empty($this->nameElement)) return '';
      return '</'.$this->nameElement.'>';
    }
    
    
    
    
    /**
     * Return css syntax from array
     * @param array $array
     * @return string
     */                   
    public function getSubAttrs($array)
    {
      foreach($array as $key=>$value){
        $out .= $key.':'.$value.'; ';
      
      }
      return $out;
    }
        
    
    
    
    /**
     * Set Attrs
     * @param mixed $value
     * @param string|null $name
     */            
    public function setAttrs($value,$name=null)
    {
      if(is_null($name)){
        $this->attrs[] = $value;
      }else{
        $this->attrs[$name] = $value;
      }
    }
    
    
    
    
    /**
     * Return attrs of html element
     * @return mixed
     */
    public function getAttrs()
    {
      foreach((array) $this->attrs as $key=>$value){
          $out .= (is_int($key)?$value:$key).'="'.(is_array($value)?$this->getSubAttrs($value):$value).'" ';
      }
      return $out;
    }
    
    
    
    /**
     * Set contents in html
     * @param mixed $html     
     */   
    public function setHtml($html)
    {
      $this->children[] = $html;
      return $this;
    }
    
    
    
    /**
     * Set contents in type only text
     * @param mixed $text     
     */   
    public function setText($text)
    {
      return $this->setHtml(htmlspecialchars($text));
    }
    
    
    
    
    /**
     * Return true or false if is nameElement in emptyElement 
     * @return bool
     */   
    public function isInEmpty()
    {
      return in_array($this->nameElement,$this->emptyElement);
    }
  
  
    /**
     * Create Children Element
     * @param string $name
     * @param array $attrs
     * @return object
     */   
    public function create($name, $attrs=array())
    {
      $child = self::el($name, $attrs);
      $this->addChildren($child);
		  return $child;
    }
    
    
    
    
    /**
     * Add children 
     * @param object $child     
     * @return object
     */   
    public function addChildren($child)
    {
      if($child instanceof Html){
         $this->children[] = $child;
      
      }
      return $this;
    }
        
    
    
    /**
     * Render html code
     * @return string
     */   
    public function render()
    {
      if(!$this->isShow()) return '';
      $render = $this->startElement();
      foreach($this->children as $child){
        $render .= ($child instanceof Html)?$child->render():$child;
      
      }
      
      if(!$this->isInEmpty()) $render .= $this->endElement();
      return $render;
    }
    
        
    
    
    /**
     * Return $this->render();
     * @return string
     */       
    public function __toString()
    {
      return $this->render();
    }
  
  }

?>